# -*- coding:utf-8 -*-
from py2neo import Graph, Node, Relationship, cypher, Path
import neo4j
class Neo4j():
    graph = None
    def __init__(self):
        print("create neo4j class ...")

    def connectDB(self):
        self.graph = Graph("http://localhost:7474", username="neo4j", password="123456")

    def matchItembyTitle(self,value):

        sql = "MATCH (n{ title: '" + str(value) + "' }) return n;"
        answer = self.graph.run(sql).data()
        return answer

    # 不用，根据title值返回互动百科item
    def matchHudongItembyTitle(self,value):
        sql = "MATCH (n:HudongItem { title: '" + str(value) + "' }) return n;"
        try:
            answer = self.graph.run(sql).data()
        except:
            print(sql)
        return answer

    # 根据entity的名称返回关系,模糊查询
    def getEntityRelationbyEntity(self,value):
        answer = self.graph.run("MATCH (n1) - [rel] -> (n2)  WHERE n1.title =~\".*" +str(value)+".*\" RETURN n1,rel,n2").data()
        # print("answer[0].length="+str(len(answer[0])))
        return answer

    # 查找entity1及其对应的关系（与getEntityRelationbyEntity的差别就是返回值不一样）
    def findRelationByEntity(self,entity1):
        answer = self.graph.run("MATCH (n1 {title:\""+str(entity1)+"\"})- [rel] -> (n2) RETURN n1,rel,n2" ).data()
        # if(answer is None):
        # 	answer = self.graph.run("MATCH (n1:NewNode {title:\""+entity1+"\"})- [rel] -> (n2) RETURN n1,rel,n2" ).data()

        return answer

    # 查找entity2及其对应的关系
    def findRelationByEntity2(self,entity2):
        answer = self.graph.run("MATCH (n1)- [rel] -> (n2 {title:\""+str(entity2)+"\"}) RETURN n1,rel,n2" ).data()

        # if(answer is None):
        # 	answer = self.graph.run("MATCH (n1)- [rel] -> (n2:NewNode {title:\""+entity1+"\"}) RETURN n1,rel,n2" ).data()
        return answer

    # 根据entity1和关系查找enitty2
    def findOtherEntities(self,entity,relation):
        answer = self.graph.run("MATCH (n1 {title:\"" + str(entity) + "\"})- [rel {type:\""+str(relation)+"\"}] -> (n2) RETURN n1,rel,n2" ).data()
        #if(answer is None):
        #	answer = self.graph.run("MATCH (n1:NewNode {title:\"" + entity + "\"})- [rel:RELATION {type:\""+relation+"\"}] -> (n2) RETURN n1,rel,n2" ).data()

        return answer

    #根据entity2和关系查找enitty1
    def findOtherEntities2(self,entity,relation):
        answer = self.graph.run("MATCH (n1)- [rel {type:\""+str(relation)+"\"}] -> (n2 {title:\"" + str(entity) + "\"}) RETURN n1,rel,n2" ).data()
        #if(answer is None):
        #	answer = self.graph.run("MATCH (n1)- [rel:RELATION {type:\""+relation+"\"}] -> (n2:NewNode {title:\"" + entity + "\"}) RETURN n1,rel,n2" ).data()

        return answer

    # 根据两个实体查询它们之间的最短路径
    def findRelationByEntities(self,entity1,entity2):
        answer = self.graph.run("MATCH (p1 {title:\"" + str(entity1) + "\"}),(p2 {title:\""+str(entity2)+"\"}),p=shortestpath((p1)-[rel*]-(p2)) RETURN rel").evaluate()
        #answer = self.graph.run("MATCH (p1:HudongItem {title:\"" + entity1 + "\"})-[rel:RELATION]-(p2:HudongItem{title:\""+entity2+"\"}) RETURN p1,p2").data()

        if(answer is None):
            answer = self.graph.run("MATCH (p1:HudongItem {title:\"" + str(entity1) + "\"}),(p2:NewNode {title:\""+str(entity2)+"\"}),p=shortestpath((p1)-[rel:RELATION*]-(p2)) RETURN p").evaluate()
        if(answer is None):
            answer = self.graph.run("MATCH (p1:NewNode {title:\"" + str(entity1) + "\"}),(p2:HudongItem{title:\""+str(entity2)+"\"}),p=shortestpath((p1)-[rel:RELATION*]-(p2)) RETURN p").evaluate()
        if(answer is None):
            answer = self.graph.run("MATCH (p1:NewNode {title:\"" + str(entity1) + "\"}),(p2:NewNode {title:\""+str(entity2)+"\"}),p=shortestpath((p1)-[rel:RELATION*]-(p2)) RETURN p").evaluate()
        relationDict = []
        if(answer is not None):
            for x in answer:
                tmp = {}
                start_node = x.start_node
                end_node = x.end_node
                tmp['n1'] = start_node
                tmp['n2'] = end_node
                tmp['rel'] = x
                relationDict.append(tmp)
        return relationDict

    # 查询数据库中是否有对应的实体-关系匹配
    def findEntityRelation(self, entity1, relation, entity2):
        answer = self.graph.run("MATCH (n1:{title:\"" + str(entity1) + "\"})- [rel:RELATION {type:\""+str(relation)+"\"}] -> (n2{title:\""+entity2+"\"}) RETURN n1,rel,n2" ).data()
        return answer

    # 查询数据库中所有具有关系relation的所有三元组
    def findAllByRelation(self, relation):
        print(relation)
        # Phe_has_Cause Phe_has_Mnt Cause_lead_Phe Mnt_to_Phe Mnt_has_Cause
        answer = self.graph.run("MATCH (n1)-[rel {type:\""+str(relation)+"\"}] -> (n2) RETURN n1,rel,n2").data()
        return answer

    # 查询维护方法可以解决的故障现象有哪些
    def getPheByMnt(self, Mnt):
        # answer = self.graph.run("MATCH (n1:FaultMnt )-[rel {type:\"Mnt_to_Phe\"}]-(n2:FaultPhe) WHERE n1.title=~\".*"+str(Mnt)+".*\" RETURN n1, rel, n2").data()
        answer = self.graph.run("MATCH (n1:FaultMnt )-[rel:Mnt_to_Phe]-(n2:FaultPhe) WHERE n1.title=~\".*"+str(Mnt)+".*\" RETURN n1, rel, n2").data()
        return answer

    # 查询维护方法可以针对的故障原因
    def getCauseByMnt(self, Mnt):
        # answer = self.graph.run("MATCH (n1:FaultMnt )-[rel {type:\"Mnt_to_Cause\"}]-(n2:FaultCause) WHERE n1.title=~\".*"+str(Mnt)+".*\" RETURN n1, rel, n2").data()
        answer = self.graph.run("MATCH (n1:FaultMnt )-[rel :Mnt_has_Cause]-(n2:FaultCause) WHERE n1.title=~ \".*"+str(Mnt)+".*\" RETURN n1, rel, n2").data()
        return answer

    # 获得该故障原因会引起哪些故障现象
    def getPheByCause(self,Cause):
        answer = self.graph.run("MATCH (n1:FaultCause )-[rel {type:\"Cause_lead_Phe\"}]-(n2:FaultPhe) WHERE n1.title=~\".*"+str(Cause)+".*\" RETURN n1, rel, n2").data()
        return answer

    # 获得故障现象所对应的维护方法
    def getMntByPhe(self,Phe):
        answer = self.graph.run("MATCH (n1:FaultPhe )-[rel {type:\"Phe_has_Mnt\"}]-(n2:FaultMnt) WHERE n1.title=~\".*"+str(Phe)+".*\" RETURN n1, rel, n2").data()
        return answer

    # 模糊查询可能产生该故障现象的所有原因
    def getCauseByPhe(self, Phe):
        answer = self.graph.run("MATCH (n1:FaultPhe)-[rel {type:\"Phe_has_Cause\"}]-(n2:FaultCause) WHERE n1.title=~\".*"+str(Phe)+".*\" RETURN n1, rel, n2").data()
        return answer

    # 根据type类型（FaultPhe,FaultCause,FaultMnt）查询该类型的所有实体
    def getEntitiesByTitle(self, type):
        answer = self.graph.run("MATCH (n:"+type+") RETURN n").data()
        return answer

def findSimiEntity(db,entity_type, entity):
    # 根据entity_type找到所有该类型的实体
    if entity_type == "phe":
        type = "FaultPhe"
    elif entity_type == "mnt":
        type = "FaultMnt"
    elif entity_type == "cau":
        type = "FaultCause"

    # entities表示该类型的所有实体,需要通过
    entities = db.getEntitiesByTitle(type)
    print(entity_type+"类型的实体数："+str(len(entities)))
    for i in range(len(entities)):
        print(entities[i]['n']['title'])
    # 接下来将在所有实体中找出与识别出的实体最相似的实体

    # res_entity = ""
    # return res_entity


if __name__=='__main__':
    db = Neo4j()
    db.connectDB()
    findSimiEntity(db,"phe","点蚀")